import java.io.File;
import java.util.Scanner;

import asset.Define;
import asset.Excute;
import asset.PC;
import asset.RegOrder;

/**
 * Simulate Enterance
 */
public class Simulator {
    private static Scanner scanner;

    /**
     * args can be omited<p/>
     * args[0] : filepath : string <p/>
     * args[1] : maxpath : plus int <p/>
     * args[2] : delaying enable : true or false <p/>
     */
    public static void main(String[] args) throws Exception {
        int maxpath = -1;
        // fundamental settings
        if (args == null || args.length == 0) {
            Excute.setEnableDelaying(true);
            scanner = new Scanner(System.in);
        }
        else {
            try {
                File file = new File(args[0]);
                scanner = new Scanner(file);
            } catch (Exception e) {
                System.out.println(e.getMessage());
                return;
            }
            boolean enableDelaying = true;
            if (args.length > 1) {
                maxpath = Define.zeroExtNum(args[1]);
            }
            if (args.length > 2 && args[2].equals("false")) {
                enableDelaying = false;
            }
            Excute.setEnableDelaying(enableDelaying);
        }
        String code;
        String line = "";
        boolean readover = false;
        //Register order and load to PC
        while (!readover) {

            do {
                try {
                    line = scanner.nextLine();
                } catch (Exception e) {
                    readover = false;
                    continue;
                }
                readover = !scanner.hasNext();
            } while (!readover && line == "");

            if (RegOrder.checkMachineInst(line)) {
                code = DisAssembler.decode(RegOrder.filterMachineCode(line));
                PC.loadInst(new RegOrder(line,code));
            }
            else {
                code = line;
                PC.loadInst(new RegOrder(code));
            }
        }
        //run order
        if (maxpath > 0) {
            while (!PC.isEndSignal() && maxpath > 0) {
                Excute.run(PC.getOrder().getDisasmbCodeString());
                maxpath--;
            }
        } else {
            while (!PC.isEndSignal()) {
                Excute.run(PC.getOrder().getDisasmbCodeString());
            }
        }
        scanner.close();
    }
}